#pragma once
#include "sock.hpp"
#include <sys/select.h>

class SelectServer
{
public:
    SelectServer(uint16_t port = 8080)
        : _port(port)
    {
        _listen_sock = _sock.Socket();
        _sock.Bind(_listen_sock, _port);
        _sock.Listen(_listen_sock);

        std::cout << "sock init success" << std::endl;
    }

    void start()
    {
        fd_set rfds;
        FD_ZERO(&rfds);

        while (true)
        {
            FD_SET(_listen_sock, &rfds);
            struct timeval timeout = {0, 0}; // 0,0 非阻塞

            // int n = select(_listen_sock + 1, &rfds, nullptr, nullptr, nullptr); // 默认阻塞
            int n = select(_listen_sock + 1, &rfds, nullptr, nullptr, &timeout); //   非阻塞

            switch (n)
            {
            case 0:
                std::cout << "time out" << std::endl;
                break;
            case -1:
                std::cout << "error" << errno << ":" << strerror(errno) << std::endl;
                break;
            default:
                std::cout << "fd init" << std::endl;
                FD_CLR(_listen_sock, &rfds);
                func(_listen_sock, rfds);
                break;
            }
            sleep(1);
        }
    }

    ~SelectServer()
    {
        if (_listen_sock >= 0)
        {
            close(_listen_sock);
        }
    }

private:
    void func(int fd, fd_set &rfds)
    {
        if (FD_ISSET(fd, &rfds))
        {
            // accept
            _sock.Accept(fd);
            std::cout << "accept" << std::endl;
        }
    }

private:
    uint16_t _port;
    int _listen_sock;
    Sock _sock;
};
